﻿using NLog.Fluent;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Diagnostics.Eventing.Reader;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using thinger.AutomaticStoreMotionModels;

namespace thinger.AutomaticStoreMotionDAL
{
    public class Motion
    {
        #region 字段和属性
        /// <summary>
        /// 板卡初始化成功
        /// </summary>
        public bool initedOK;

        /// <summary>
        /// 坐标系建立成功
        /// </summary>
        public bool bulidOk;

        public BasicParam basicParam = new BasicParam();

        public AdvancedParam advancedParam = new AdvancedParam();

        public string configFile = Application.StartupPath + "\\Config\\Config.ini";
        #endregion

        #region 参数的保持和加载
        public OperationResult SaveBasicParam()
        {
            //先讲对象转换成JSON字符串
            string json = JSONHelper.EntityToJSON(basicParam);
            //写入INI文件
            if (IniConfigHelper.WriteIniData("参数", "基础参数", json, configFile))
            {
                return OperationResult.CreateSuccessResut();
            }
            else
            {
                return OperationResult.CreateFailResut();
            }
        }

        public OperationResult SaveAdvancedParam()
        {
            //先讲对象转换成JSON字符串
            string json = JSONHelper.EntityToJSON(advancedParam);
            //写入INI文件
            if (IniConfigHelper.WriteIniData("参数", "高级参数", json, configFile))
            {
                return OperationResult.CreateSuccessResut();
            }
            else
            {
                return OperationResult.CreateFailResut();
            }
        }

        public OperationResult Loadparam()
        {
            try
            {
                // 获取基础参数json字符串
                string jsonBasic = IniConfigHelper.ReadIniData("参数", "基础参数", JSONHelper.EntityToJSON(basicParam), configFile);
                //json转换成对象
                basicParam = JSONHelper.JSONToEntity<BasicParam>(jsonBasic);

                //获取高级参数json字符串
                string jsonAdvanced = IniConfigHelper.ReadIniData("参数", "高级参数", JSONHelper.EntityToJSON(advancedParam), configFile);
                //json转换成对象
                advancedParam = JSONHelper.JSONToEntity<AdvancedParam>(jsonAdvanced);
            }
            catch (Exception ex)
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = ex.Message
                };
            }
            return OperationResult.CreateSuccessResut();
        }

        #endregion

        //**********轴控制公共方法**********
        #region 轴卡操作错误消息处理
        /// <summary>
        /// 轴卡操作错误消息处理
        /// </summary>
        /// <param name="command"></param>
        /// <param name="error"></param>
        /// <remarks>
        /// 0 指令执行成功
        /// 1 指令执行错误
        /// 2 license 不支持
        /// 7 指令参数错误
        /// 8 不支持该指令
        /// -1~-5 主机和运动控制器通讯失败
        /// -6 打开控制器失败
        /// -7 运动控制器没有响应
        /// -8 多线程资源忙 
        /// </remarks>
        private void ErrorHandler(string command, short error)
        {
            string result = string.Empty;
            switch (error)
            {
                case 0: break;
                case 1: result = $"{command}指令执行错误"; break;
                case 2: result = $"{command}license 不支持"; break;
                case 7: result = $"{command}指令参数错误"; break;
                case 8: result = $"{command}不支持该指令"; break;
                case -1:
                case -2:
                case -3:
                case -4:
                case -5: result = $"{
                    
                    
                    }主机和运动控制器通讯失败"; break;
                case -6: result = $"{command}打开控制器失败"; break;
                case -7: result = $"{command}运动控制器没有响应"; break;
                case -8: result = $"{command}多线程资源忙"; break;
                default: result = $"{command}未知错误"; break;
            }
            if (result.Length > 0)
            {
                throw new Exception(result);
            }
        }
        #endregion

        #region 通用初始化验证
        private OperationResult CommonInitedValidate()
        {
            if (!initedOK)
            {
                return new OperationResult
                {
                    IsSuccess = false,
                    ErrorMsg = "通用初始化未完成"
                };
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 通用运动初始化验证
        private OperationResult CommonMotionValidate(short aixs)
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //轴运动判断
            if (IsMoving(aixs))
            {
                result.IsSuccess = false;
                result.ErrorMsg = "正在运动";
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }

        //判断某个轴是否运行
        private bool IsMoving(short aixs)
        {
            OperationResult result = new OperationResult();
            try
            {
                //运动指令返回值
                short error = GTS.GT_GetSts(aixs, out int sts, 1, out uint pClock);
                ErrorHandler("GT_GetSts", error);
                return (sts & 0 * 0400) != 0;
            }
            catch (Exception)
            {
                return true;
            }
        }
        #endregion

      

        //*********轴卡操作*******
        #region 板卡初始化
        public OperationResult InitCard()
        {
            //读取配置
            OperationResult result = Loadparam();
            if (!result.IsSuccess) return result;

            //运动卡指令的返回值
            short error;
            try
            {
                //切换卡号
                error = GTS.GT_SetCardNo(advancedParam.nudCardNo);
                ErrorHandler("GT_SetCardNo", error);

                //打开控制器
                error = GTS.GT_Open(0, 0);
                ErrorHandler("GT_Open", error);

                //复位控制器
                error = GTS.GT_Reset();
                ErrorHandler("GT_Reset", error);

                //加载配置文件
                error = GTS.GT_LoadConfig("Config\\" + advancedParam.cobCfg);
                ErrorHandler("GT_LoadConfig", error);

                //清楚轴标志
                error = GTS.GT_ClrSts(1, advancedParam.nudAxisCount);
                ErrorHandler("GT_ClrSts", error);

                //使能驱动
                for (short i = 1; i <= advancedParam.nudAxisCount; i++)
                {
                    error = GTS.GT_AxisOn(i);
                    ErrorHandler("GT_AxisOn", error);
                }

                initedOK = true;
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 板卡关闭
        public OperationResult CloseCard()
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //关闭轴
            for (short i = 1; i <= advancedParam.nudAxisCount; i++)
            {
                CloseAxis(i);
                if (!result.IsSuccess) return result;
            }

            //关闭卡
            try
            {
                short error = GTS.GT_Close();
                ErrorHandler("GT_Close", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        //*******轴卡的IO控制*******
        #region 获取输入
        public short GetInput()
        {
            //验证板卡是否正常初始化
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return 0;

            //定义函数返回值
            short error;

            try
            {
                //获取板卡输入
                error = GTS.GT_GetDi(GTS.MC_GPI, out int diValue);
                ErrorHandler("GT_GetDi", error);
                return (short)diValue;
            }
            catch (Exception)
            {
                return 0;
            }
        }
        #endregion

        #region 获取指定位输入
        public bool GetInput(int index)
        {
            short diValue = GetInput();
            if ((diValue & (1 << (index - 1))) == (1 << (index - 1)))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 获取输出
        public short GetOutput()
        {
            //验证板卡是否正常初始化
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return 0;

            //定义函数返回值
            short error;

            try
            {
                //获取板卡输入
                error = GTS.GT_GetDo(GTS.MC_GPO, out int doValue);
                ErrorHandler("GT_GetDo", error);
                return (short)doValue;
            }
            catch (Exception)
            {
                return 0;
            }
        }
        #endregion

        #region 获取指定位输入
        public bool GetOutput(int index)
        {
            short doValue = GetOutput();
            if ((doValue & (1 << (index - 1))) == (1 << (index - 1)))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        #endregion

        #region 根据索引操作位
        public OperationResult SetOutput(int index, bool open)
        {
            //验证板卡是否正常初始化
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //定义返回值
            short error;

            try
            {
                //位操作
                error = GTS.GT_SetDoBit(GTS.MC_GPO, (short)index, (short)(open ? 1 : 0));
                ErrorHandler("GT_SetDoBit", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        //******轴状态监控***********
        #region 等待轴正常停止
        public OperationResult WaitStop(short axis)
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //定义轴指令返回值
            short error;
            //轴状态
            int sts;

            do
            {
                try
                {
                    error = GTS.GT_GetSts(axis, out sts, 1, out uint pClock);
                    ErrorHandler("GT_GetSts", error);
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.ErrorMsg = ex.Message;
                    return result;
                }
            } while ((sts & 0 * 400) != 0);
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 等待回原点停止
        public OperationResult WaitHomeStop(short axis)
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //定义轴指令返回值
            short error;
            //轴回零状态
            ushort sts;

            do
            {
                try
                {
                    error = GTS.GT_HomeSts(axis, out sts);
                    ErrorHandler("GT_HomeSts", error);
                }
                catch (Exception ex)
                {
                    result.IsSuccess = false;
                    result.ErrorMsg = ex.Message;
                    return result;
                }
            } while (sts == 0);
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 获取实时位置
        public double GetCmdPos(short axis)
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return -999999.0;

            //定义指令返回值
            short error;

            try
            {
                error = GTS.GT_GetAxisPrfPos(axis, out double pValue, 1, out uint pClock);
                ErrorHandler("GT_GetAxisPrfPos", error);

                if (axis == advancedParam.nudAxisXNo)
                {
                    pValue = pValue / advancedParam.nudAxisXUnit;
                }
                else if (axis == advancedParam.nudAxisYNo)
                {
                    pValue = pValue / advancedParam.nudAxisYUnit;
                }
                else if (axis == advancedParam.nudAxisZNo)
                {
                    pValue = pValue / advancedParam.nudAxisZUnit;
                }
                return pValue;
            }
            catch (Exception)
            {
                return -999999.0;
            }
        }
        #endregion

        //******轴控操作***********
        #region 轴关闭
        public OperationResult CloseAxis(short aixsNo)
        {
            //确认通用初始化完成
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;

            //运动卡指令的返回值
            short error;
            try
            {
                //轴伺服off操作
                error = GTS.GT_AxisOff(aixsNo);
                ErrorHandler("GT_AxisOff", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 停止单轴
        public OperationResult StopAxis(short axis)
        {
            //通用初始化验证
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;
            //定义返回值
            short error;
            try
            {
                error = GTS.GT_Stop(1 << (axis - 1), 1 << (axis - 1));
                ErrorHandler("GT_Stop", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 停止所有的轴
        public OperationResult StopAllAxis()
        {
            //通用初始化验证
            OperationResult result = CommonInitedValidate();
            if (!result.IsSuccess) return result;
            //定义返回值
            short error;
            try
            {
                error = GTS.GT_Stop(0x0F, 0x0F);
                ErrorHandler("GT_Stop", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 点动
        public OperationResult JogMove(short aixs, double vel = 10, double acc = 0.0125)
        {
            //通用运行初始化验证
            OperationResult result = CommonMotionValidate(aixs);
            if (!result.IsSuccess) return result;

            //定义一个轴控返回值
            short error;

            try
            {
                // 将 AXIS 轴设为 Jog 模式
                error = GTS.GT_PrfJog(aixs);
                ErrorHandler("GT_PrfJog", error);

                //创建一个TJogPrm对象
                GTS.TJogPrm jogPrm;

                // 读取 Jog 运动参数(需要读取全部运动参数到上位机变量)
                error = GTS.GT_GetJogPrm(aixs, out jogPrm);
                ErrorHandler("GT_GetJogPrm", error);

                //给Jog赋值
                jogPrm.acc = acc;
                jogPrm.dec = acc;
                jogPrm.smooth = 0.8; //0~1之间，越接近1，越平滑

                // 设置 Jog 运动参数
                error = GTS.GT_SetJogPrm(aixs, ref jogPrm);
                ErrorHandler("GT_SetJogPrm", error);

                // 设置 AXIS 轴的目标速度
                error = GTS.GT_SetVel(aixs, vel);
                ErrorHandler("GT_SetVel", error);

                // 启动 AXIS 轴的运动
                error = GTS.GT_Update(1 << (aixs - 1));   //aixs 轴号从1开始
                ErrorHandler("GT_Update", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 单轴绝对定位
        public OperationResult MoveAbs(short axis, double pos, double vel = 10, double acc = 0.0125)
        {
            //通用运行初始化验证
            OperationResult result = CommonMotionValidate(axis);
            if (!result.IsSuccess) return result;

            //定义一个轴控返回值
            short error;

            try
            {
                //清除标志位
                error = GTS.GT_ClrSts(axis, 1);
                ErrorHandler("GT_ClrSts", error);

                // 将 AXIS 轴设为点位模式
                error = GTS.GT_PrfTrap(axis);
                ErrorHandler("GT_PrfTrap", error);

                //点位运动参数
                GTS.TTrapPrm trapPrm = new GTS.TTrapPrm();

                // 读取点位运动参数(需要读取所有运动参数到上位机变量)
                error = GTS.GT_GetTrapPrm(axis, out trapPrm);
                ErrorHandler("GT_GetTrapPrm", error);

                int posPulse;
                int velPulse;
                int accPulse;
                if (axis == advancedParam.nudAxisXNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisXUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisXUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisXUnit));
                }
                else if (axis == advancedParam.nudAxisYNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisYUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisYUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisYUnit));
                }
                else if (axis == advancedParam.nudAxisZNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisZUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisZUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisZUnit));
                }
                else
                {
                    posPulse = Convert.ToInt32(pos);
                    velPulse = Convert.ToInt32(vel);
                    accPulse = Convert.ToInt32(acc);
                }

                // 设置需要修改的运动参数
                trapPrm.acc = accPulse;
                trapPrm.dec = accPulse;
                trapPrm.smoothTime = 25; //0~50之间，平滑时间越大，加减速过程越平稳

                // 设置点位运动参数
                error = GTS.GT_SetTrapPrm(axis, ref trapPrm);
                ErrorHandler("GT_SetTrapPrm", error);

                // 设置 AXIS 轴的目标位置
                error = GTS.GT_SetPos(axis, posPulse);
                ErrorHandler("GT_SetPos", error);

                // 设置AXIS轴的目标速度
                error = GTS.GT_SetVel(axis, velPulse);
                ErrorHandler("GT_SetVel", error);

                // 启动AXIS轴的运动
                error = GTS.GT_Update(1 << (axis - 1));
                ErrorHandler("GT_Update", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();

        }
        #endregion

        #region 单轴相对定位
        public OperationResult MoveRelative(short axis, double pos, double vel = 10, double acc = 0.0125)
        {
            //通用运行初始化验证
            OperationResult result = CommonMotionValidate(axis);
            if (!result.IsSuccess) return result;

            //获取当前位置
            double actPos = GetCmdPos(axis);
            if (actPos < -1000000) return new OperationResult() { IsSuccess = false, ErrorMsg = "当前位置读取错误" };

            //定义一个轴控返回值
            short error;

            try
            {
                //清除标志位
                error = GTS.GT_ClrSts(axis, 1);
                ErrorHandler("GT_ClrSts", error);

                // 将 AXIS 轴设为点位模式
                error = GTS.GT_PrfTrap(axis);
                ErrorHandler("GT_PrfTrap", error);

                //点位运动参数
                GTS.TTrapPrm trapPrm = new GTS.TTrapPrm();

                // 读取点位运动参数(需要读取所有运动参数到上位机变量)
                error = GTS.GT_GetTrapPrm(axis, out trapPrm);
                ErrorHandler("GT_GetTrapPrm", error);

                int posPulse;
                int velPulse;
                int accPulse;
                if (axis == advancedParam.nudAxisXNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisXUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisXUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisXUnit));
                }
                else if (axis == advancedParam.nudAxisYNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisYUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisYUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisYUnit));
                }
                else if (axis == advancedParam.nudAxisZNo)
                {
                    posPulse = Convert.ToInt32(Math.Round(pos * advancedParam.nudAxisZUnit));
                    velPulse = Convert.ToInt32(Math.Round(vel * advancedParam.nudAxisZUnit));
                    accPulse = Convert.ToInt32(Math.Round(acc * advancedParam.nudAxisZUnit));
                }
                else
                {
                    posPulse = Convert.ToInt32(pos);
                    velPulse = Convert.ToInt32(vel);
                    accPulse = Convert.ToInt32(acc);
                }

                // 设置需要修改的运动参数
                trapPrm.acc = accPulse;
                trapPrm.dec = accPulse;
                trapPrm.smoothTime = 25; //0~50之间，平滑时间越大，加减速过程越平稳

                // 设置点位运动参数
                error = GTS.GT_SetTrapPrm(axis, ref trapPrm);
                ErrorHandler("GT_SetTrapPrm", error);

                // 设置 AXIS 轴的目标位置
                error = GTS.GT_SetPos(axis, posPulse);
                ErrorHandler("GT_SetPos", error);

                // 设置AXIS轴的目标速度
                error = GTS.GT_SetVel(axis, velPulse);
                ErrorHandler("GT_SetVel", error);

                // 启动AXIS轴的运动
                error = GTS.GT_Update(1 << (axis - 1));
                ErrorHandler("GT_Update", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();

        }
        #endregion

        #region 根据轴号返回轴的相关信息
        private Axis GetAxisInfo(short axis)
        {
            if (axis == advancedParam.nudAxisXNo)
            {
                return new Axis()
                {
                    AxisNo = advancedParam.nudAxisXNo,
                    AxisHomeDir = advancedParam.cobAxisXHomeDir == "正向" ? 1 : -1,
                    AxisHomePos = advancedParam.nudAxisXHomePos,
                    AxisHomeNeg = advancedParam.nudAxisXHomeNeg,
                    AxisMoveVel = basicParam.nudAxisXAutoSpeed,
                    AxisHomeVel = basicParam.nudAxisXAutoSpeed * 0.25,
                    AxisHomeOffset = advancedParam.nudAxisXHomeOffset,
                    AxisHomeAcc = advancedParam.nudAxisXAcc
                };
            }
            else if (axis == advancedParam.nudAxisYNo)
            {
                return new Axis()
                {
                    AxisNo = advancedParam.nudAxisYNo,
                    AxisHomeDir = advancedParam.cobAxisYHomeDir == "正向" ? 1 : -1,
                    AxisHomePos = advancedParam.nudAxisYHomePos,
                    AxisHomeNeg = advancedParam.nudAxisYHomeNeg,
                    AxisMoveVel = basicParam.nudAxisYAutoSpeed,
                    AxisHomeVel = basicParam.nudAxisYAutoSpeed * 0.25,
                    AxisHomeOffset = advancedParam.nudAxisYHomeOffset,
                    AxisHomeAcc = advancedParam.nudAxisYAcc
                };
            }
            else if (axis == advancedParam.nudAxisZNo)
            {
                return new Axis()
                {
                    AxisNo = advancedParam.nudAxisZNo,
                    AxisHomeDir = advancedParam.cobAxisZHomeDir == "正向" ? 1 : -1,
                    AxisHomePos = advancedParam.nudAxisZHomePos,
                    AxisHomeNeg = advancedParam.nudAxisZHomeNeg,
                    AxisMoveVel = basicParam.nudAxisZAutoSpeed,
                    AxisHomeVel = basicParam.nudAxisZAutoSpeed * 0.25,
                    AxisHomeOffset = advancedParam.nudAxisZHomeOffset,
                    AxisHomeAcc = advancedParam.nudAxisZAcc
                };
            }
            else
            {
                return null;
            }
        }
        #endregion

        #region 轴清零
        public OperationResult ZeroPos(short axis)
        {
            //通用运行初始化验证
            OperationResult result = CommonMotionValidate(axis);
            if (!result.IsSuccess) return result;

            //定义指令返回值
            short error;
            try
            {
                error = GTS.GT_ZeroPos(axis, 1);
                ErrorHandler("GT_ZeroPos", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }
            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 单轴回原点
        public OperationResult HomeAxis(short axis)
        {
            //通用运行初始化验证
            OperationResult result = CommonMotionValidate(axis);
            if (!result.IsSuccess) return result;

            //获取轴相关信息
            Axis axisInfo = GetAxisInfo(axis);
            if (axisInfo == null) return new OperationResult() { IsSuccess = false, ErrorMsg = "轴信息获取失败" };

            //向复位方向走一段距离，保证能够撞上限位停止
            result = MoveRelative(axisInfo.AxisNo, axisInfo.AxisHomeNeg * axisInfo.AxisHomeDir, axisInfo.AxisMoveVel, axisInfo.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            //等待轴停止
            result = WaitStop(axisInfo.AxisNo);
            if (!result.IsSuccess) return result;

            //位置清零
            result = ZeroPos(axisInfo.AxisNo);
            if (!result.IsSuccess) return result;

            //往复位的反方向运行一段距离
            result = MoveRelative(axisInfo.AxisNo, axisInfo.AxisHomePos * axisInfo.AxisHomeDir * -1, axisInfo.AxisMoveVel, axisInfo.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            //等待轴停止
            result = WaitStop(axisInfo.AxisNo);
            if (!result.IsSuccess) return result;

            //定义指令返回值
            short error;

            try
            {
                //状态清零
                error = GTS.GT_ClrSts(axisInfo.AxisNo, 1);
                ErrorHandler("GT_ClrSts", error);

                //
                error = GTS.GT_HomeInit();
                ErrorHandler("GT_HomeInit", error);

                error = GTS.GT_SetCaptureMode(axisInfo.AxisNo, 1);
                ErrorHandler("GT_SetCaptureMode", error);

                error = GTS.GT_SetCaptureSense(axisInfo.AxisNo, 1, 0);
                ErrorHandler("GT_SetCaptureSense", error);
                //速度、加速度转换
                double axisHomeVelPulse, axisHomeAccPulse;
                int axisHomeOffsetPulse;
                if (axisInfo.AxisNo == advancedParam.nudAxisXNo)
                {
                    axisHomeVelPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeVel * advancedParam.nudAxisXUnit));
                    axisHomeAccPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeAcc * advancedParam.nudAxisXUnit));
                    axisHomeOffsetPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeOffset * advancedParam.nudAxisXUnit));
                }
                else if (axisInfo.AxisNo == advancedParam.nudAxisYNo)
                {
                    axisHomeVelPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeVel * advancedParam.nudAxisYUnit));
                    axisHomeAccPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeAcc * advancedParam.nudAxisYUnit));
                    axisHomeOffsetPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeOffset * advancedParam.nudAxisYUnit));
                }
                else if (axisInfo.AxisNo == advancedParam.nudAxisZNo)
                {
                    axisHomeVelPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeVel * advancedParam.nudAxisZUnit));
                    axisHomeAccPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeAcc * advancedParam.nudAxisZUnit));
                    axisHomeOffsetPulse = Convert.ToInt32(Math.Round(axisInfo.AxisHomeOffset * advancedParam.nudAxisZUnit));
                }
                else
                {
                    axisHomeVelPulse = Convert.ToInt32(axisInfo.AxisHomeVel);
                    axisHomeAccPulse = Convert.ToInt32(axisInfo.AxisHomeAcc);
                    axisHomeOffsetPulse = Convert.ToInt32(axisInfo.AxisHomeOffset);
                }

                error = GTS.GT_Home(axisInfo.AxisNo, -200000, axisHomeVelPulse, axisHomeAccPulse, axisHomeOffsetPulse);
                ErrorHandler("GT_Home", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }

            //等待回原点完成
            result = WaitHomeStop(axisInfo.AxisNo);
            if (!result.IsSuccess) return result;

            //位置清零
            result = ZeroPos(axisInfo.AxisNo);
            if (!result.IsSuccess) return result;

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 多轴回原点
        public OperationResult HomeAllAxis()
        {
            //Z轴回原点
            OperationResult result = HomeAxis(advancedParam.nudAxisZNo);
            if (!result.IsSuccess) return result;

            //获取轴信息
            Axis axisInfoX = GetAxisInfo(advancedParam.nudAxisXNo);
            if (axisInfoX == null) return new OperationResult() { IsSuccess = false, ErrorMsg = "轴信息获取失败" };

            Axis axisInfoY = GetAxisInfo(advancedParam.nudAxisYNo);
            if (axisInfoY == null) return new OperationResult() { IsSuccess = false, ErrorMsg = "轴信息获取失败" };

            //向复位方向走一段距离，保证能够撞上限位停止
            result = MoveRelative(axisInfoX.AxisNo, axisInfoX.AxisHomeNeg * axisInfoX.AxisHomeDir, axisInfoX.AxisMoveVel, axisInfoX.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            result = MoveRelative(axisInfoY.AxisNo, axisInfoY.AxisHomeNeg * axisInfoY.AxisHomeDir, axisInfoY.AxisMoveVel, axisInfoY.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            //等待轴停止
            result = WaitStop(axisInfoX.AxisNo);
            if (!result.IsSuccess) return result;

            result = WaitStop(axisInfoY.AxisNo);
            if (!result.IsSuccess) return result;

            //位置清零
            result = ZeroPos(axisInfoX.AxisNo);
            if (!result.IsSuccess) return result;

            result = ZeroPos(axisInfoY.AxisNo);
            if (!result.IsSuccess) return result;

            //往复位的反方向运行一段距离
            result = MoveRelative(axisInfoX.AxisNo, axisInfoX.AxisHomePos * axisInfoX.AxisHomeDir * -1, axisInfoX.AxisMoveVel, axisInfoX.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            result = MoveRelative(axisInfoY.AxisNo, axisInfoY.AxisHomePos * axisInfoY.AxisHomeDir * -1, axisInfoY.AxisMoveVel, axisInfoY.AxisHomeAcc);
            if (!result.IsSuccess) return result;

            //等待轴停止
            result = WaitStop(axisInfoX.AxisNo);
            if (!result.IsSuccess) return result;

            result = WaitStop(axisInfoY.AxisNo);
            if (!result.IsSuccess) return result;

            //定义指令返回值
            short error;

            try
            {
                //状态清零
                error = GTS.GT_ClrSts(axisInfoX.AxisNo, 1);
                ErrorHandler("GT_ClrSts", error);

                error = GTS.GT_ClrSts(axisInfoY.AxisNo, 1);
                ErrorHandler("GT_ClrSts", error);

                error = GTS.GT_HomeInit();
                ErrorHandler("GT_HomeInit", error);

                error = GTS.GT_SetCaptureMode(axisInfoX.AxisNo, 1);
                ErrorHandler("GT_SetCaptureMode", error);

                error = GTS.GT_SetCaptureMode(axisInfoY.AxisNo, 1);
                ErrorHandler("GT_SetCaptureMode", error);

                error = GTS.GT_SetCaptureSense(axisInfoX.AxisNo, 1, 0);
                ErrorHandler("GT_SetCaptureSense", error);

                error = GTS.GT_SetCaptureSense(axisInfoY.AxisNo, 1, 0);
                ErrorHandler("GT_SetCaptureSense", error);

                //速度、加速度转换
                double axisXHomeVelPulse, axisXHomeAccPulse, axisYHomeVelPulse, axisYHomeAccPulse;
                int axisXHomeOffsetPulse, axisYHomeOffsetPulse;

                axisXHomeVelPulse = Convert.ToInt32(Math.Round(axisInfoX.AxisHomeVel * advancedParam.nudAxisXUnit));
                axisXHomeAccPulse = Convert.ToInt32(Math.Round(axisInfoX.AxisHomeAcc * advancedParam.nudAxisXUnit));
                axisXHomeOffsetPulse = Convert.ToInt32(Math.Round(axisInfoX.AxisHomeOffset * advancedParam.nudAxisXUnit));

                axisYHomeVelPulse = Convert.ToInt32(Math.Round(axisInfoY.AxisHomeVel * advancedParam.nudAxisYUnit));
                axisYHomeAccPulse = Convert.ToInt32(Math.Round(axisInfoY.AxisHomeAcc * advancedParam.nudAxisYUnit));
                axisYHomeOffsetPulse = Convert.ToInt32(Math.Round(axisInfoY.AxisHomeOffset * advancedParam.nudAxisYUnit));

                error = GTS.GT_Home(axisInfoX.AxisNo, -200000, axisXHomeVelPulse, axisXHomeAccPulse, axisXHomeOffsetPulse);
                ErrorHandler("GT_Home", error);

                error = GTS.GT_Home(axisInfoY.AxisNo, -200000, axisYHomeVelPulse, axisYHomeAccPulse, axisYHomeOffsetPulse);
                ErrorHandler("GT_Home", error);
            }
            catch (Exception ex)
            {
                result.IsSuccess = false;
                result.ErrorMsg = ex.Message;
                return result;
            }

            //等待回原点完成
            result = WaitHomeStop(axisInfoX.AxisNo);
            if (!result.IsSuccess) return result;

            result = WaitHomeStop(axisInfoY.AxisNo);
            if (!result.IsSuccess) return result;

            //位置清零
            result = ZeroPos(axisInfoX.AxisNo);
            if (!result.IsSuccess) return result;

            result = ZeroPos(axisInfoY.AxisNo);
            if (!result.IsSuccess) return result;

            //建立坐标系
            result = SetCoordinate();
            if (!result.IsSuccess) return result;

            bulidOk = true;

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 2轴绝对定位
        public OperationResult Move2DAbs(short[] axis, double[] pos, double[] vel, double[] acc)
        {
            if (axis.Length == 2 && pos.Length == 2 && vel.Length == 2 && acc.Length == 2)
            {
                //判断是否满足运动要求
                OperationResult result = CommonMotionValidate(axis[0]);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(axis[1]);
                if (!result.IsSuccess) return result;

                //绝对定位
                result = MoveAbs(axis[0], pos[0], vel[0], acc[0]);
                if (!result.IsSuccess) return result;

                result = MoveAbs(axis[1], pos[1], vel[1], acc[1]);
                if (!result.IsSuccess) return result;

                //等待停止
                result = WaitStop(axis[0]);
                if (!result.IsSuccess) return result;

                result = WaitStop(axis[1]);
                if (!result.IsSuccess) return result;

                return OperationResult.CreateSuccessResut();
            }

            return new OperationResult() { IsSuccess = false, ErrorMsg = "传递参数长度不正确" };
        }
        #endregion

        #region 3轴绝对定位
        public OperationResult Move3DAbs(short[] axis, double[] pos, double[] vel, double[] acc)
        {
            if (axis.Length == 3 && pos.Length == 3 && vel.Length == 3 && acc.Length == 3)
            {
                //判断是否满足运动要求
                OperationResult result = CommonMotionValidate(axis[0]);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(axis[1]);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(axis[2]);
                if (!result.IsSuccess) return result;

                //Z轴运行至安全位置
                result = MoveAbs(axis[2], basicParam.nudAxisZSafety, vel[2], acc[2]);
                if (!result.IsSuccess) return result;

                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                //两轴定位
                result = Move2DAbs(new short[] { axis[0], axis[1] }, new double[] { pos[0], pos[1] }, new double[] { vel[0], vel[1] }, new double[] { acc[0], acc[1] });
                if (!result.IsSuccess) return result;

                //Z轴定位至工作位
                result = MoveAbs(axis[2], pos[2], vel[2], acc[2]);
                if (!result.IsSuccess) return result;

                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                return OperationResult.CreateSuccessResut();
            }
            return new OperationResult() { IsSuccess = false, ErrorMsg = "传递参数长度不正确" };
        }
        #endregion

        #region 建立插补坐标系
        public OperationResult SetCoordinate()
        {
            //定义命令返回值
            short error;

            try
            {
                //定义TCrdPrm
                GTS.TCrdPrm crdPrm = new GTS.TCrdPrm();

                //定义二维坐标系
                crdPrm.dimension = 2;

                //最大合成速度 单位pulse/ms
                crdPrm.synVelMax = 1000;

                //最大合成加速度 
                crdPrm.synAccMax = 50;

                //最小匀速时间
                crdPrm.evenTime = 500;

                //轴的对应关系
                crdPrm.profile1 = advancedParam.nudAxisXNo;
                crdPrm.profile2 = advancedParam.nudAxisYNo;

                //设置原点
                crdPrm.setOriginFlag = 1;

                //原点坐标
                crdPrm.originPos1 = 0;
                crdPrm.originPos2 = 0;

                //建立1号坐标系
                error = GTS.GT_SetCrdPrm(1, ref crdPrm);
                ErrorHandler("GT_SetCrdPrm", error);

                return OperationResult.CreateSuccessResut();
            }
            catch (Exception ex)
            {
                return new OperationResult()
                {
                    IsSuccess = false,
                    ErrorMsg = ex.Message
                };
            }
        }
        #endregion

        #region 2轴插补绝对定位
        public OperationResult MoveLineXYAbs(double[] pos, double vel, double acc)
        {
            if (pos.Length == 2)
            {
                //判断是否满足运动要求
                OperationResult result = CommonMotionValidate(advancedParam.nudAxisXNo);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(advancedParam.nudAxisYNo);
                if (!result.IsSuccess) return result;

                //判断坐标系是否建立
                if (!bulidOk) return new OperationResult() { IsSuccess = false, ErrorMsg = "坐标系未建立" };

                //获取坐标
                int posX = Convert.ToInt32(Math.Round(pos[0] * advancedParam.nudAxisXUnit));
                int posY = Convert.ToInt32(Math.Round(pos[1] * advancedParam.nudAxisXUnit));

                //定义指令返回值
                short error;

                //清除坐标系缓冲区
                error = GTS.GT_CrdClear(1, 0);
                ErrorHandler("GT_CrdClear", error);

                //往缓冲区里写数据
                error = GTS.GT_LnXY(1, posX, posY, vel, acc, 0, 0);
                ErrorHandler("GT_LnXY", error);

                //查询剩余空间
                error = GTS.GT_CrdSpace(1, out int space, 0);
                ErrorHandler("GT_CrdSpace", error);

                //启动
                error = GTS.GT_CrdStart(1, 0);
                ErrorHandler("GT_CrdSpace", error);

                //等待插补完成
                result = WaitLineStop();
                if (!result.IsSuccess) return result;

                return OperationResult.CreateSuccessResut();
            }
            return new OperationResult() { IsSuccess = false, ErrorMsg = "传递参数长度不正确" };
        }
        #endregion

        #region 等待插补完成
        public OperationResult WaitLineStop()
        {
            OperationResult result = CommonInitedValidate();
            if (result.IsSuccess) return result;

            //定义指令返回值
            short error;
            //轴状态
            short sts;

            do
            {
                try
                {
                    error = GTS.GT_CrdStatus(1, out sts, out int segment, 0);
                    ErrorHandler("GT_CrdStatus", error);
                }
                catch (Exception ex)
                {
                    return new OperationResult()
                    {
                        IsSuccess = false,
                        ErrorMsg = ex.Message
                    };
                }
            } while (sts == 1);

            return OperationResult.CreateSuccessResut();
        }
        #endregion

        #region 3轴插补定位
        public OperationResult Move3DLineAbs(short[] axis, double[] pos, double[] vel, double[] acc)
        {
            if (axis.Length == 3 && pos.Length == 3 && vel.Length == 3 && acc.Length == 3)
            {
                //判断是否满足运动要求
                OperationResult result = CommonMotionValidate(axis[0]);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(axis[1]);
                if (!result.IsSuccess) return result;

                result = CommonMotionValidate(axis[2]);
                if (!result.IsSuccess) return result;

                //Z轴运行至安全位置
                result = MoveAbs(axis[2], basicParam.nudAxisZSafety, vel[2], acc[2]);
                if (!result.IsSuccess) return result;

                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                //两轴定位
                result = MoveLineXYAbs(new double[] { pos[0], pos[1] }, vel[0], acc[0]);
                if (!result.IsSuccess) return result;

                //Z轴定位至工作位
                result = MoveAbs(axis[2], pos[2], vel[2], acc[2]);
                if (!result.IsSuccess) return result;

                result = WaitStop(axis[2]);
                if (!result.IsSuccess) return result;

                return OperationResult.CreateSuccessResut();
            }
            return new OperationResult() { IsSuccess = false, ErrorMsg = "传递参数长度不正确" };
        }
        #endregion

    }


    /// <summary>
    /// 轴相关信息
    /// </summary>
    public class Axis
    {
        /// <summary>
        /// 轴号
        /// </summary>
        public short AxisNo { get; set; }

        /// <summary>
        /// 轴寻原点方向，1、正方向，2、负方向
        /// </summary>
        public int AxisHomeDir { get; set; }

        /// <summary>
        /// 轴寻原点正向距离
        /// </summary>
        public short AxisHomePos { get; set; }

        /// <summary>
        /// 轴寻原点反向距离
        /// </summary>
        public short AxisHomeNeg { get; set; }

        /// <summary>
        /// 轴寻原点正常速度
        /// </summary>
        public double AxisMoveVel { get; set; }

        /// <summary>
        /// 轴寻原点速度
        /// </summary>
        public double AxisHomeVel { get; set; }

        /// <summary>
        /// 轴寻原点加速度
        /// </summary>
        public double AxisHomeAcc { get; set; }

        /// <summary>
        /// 轴寻原点偏移
        /// </summary>
        public short AxisHomeOffset { get; set; }
    }

}
